Ext.ux.TaskBar = function(app) {
	this.app = app;
	this.init();
}
Ext.extend(Ext.ux.TaskBar, Ext.util.Observable, {
	init : function() {
		this.startMenu = new Ext.ux.StartMenu(Ext.apply({
					iconCls : 'user',
					height : 300,
					shadow : true,
					title : 'Jack Slocum',
					width : 300
				}, this.app.startConfig));
		this.startBtn = new Ext.Button({
			text : '开始',
			id : 'ux-startbutton',
			iconCls : 'start',
			menu : this.startMenu,
			menuAlign : 'bl-tl',
			renderTo : 'ux-taskbar-start',
			clickEvent : 'mousedown',
			template : new Ext.Template(
					'<table border="0" cellpadding="0" cellspacing="0" class="x-btn-wrap"><tbody><tr>',
					'<td class="ux-startbutton-left"><i>&#160;</i></td><td class="ux-startbutton-center"><em unselectable="on"><button class="x-btn-text" type="{1}" style="height:30px;">{0}</button></em></td><td class="ux-startbutton-right"><i>&#160;</i></td>',
					"</tr></tbody></table>")
		});
		var width = Ext.get('ux-startbutton').getWidth() + 10;
		var sbBox = new Ext.BoxComponent({
					el : 'ux-taskbar-start',
					id : 'TaskBarStart',
					minWidth : width,
					region : 'west',
					split : true,
					width : width
				});
		this.tbPanel = new Ext.ux.TaskButtonsPanel({
					el : 'ux-taskbuttons-panel',
					id : 'TaskBarButtons',
					region : 'center'
				});
		var container = new Ext.ux.TaskBarContainer({
					el : 'ux-taskbar',
					layout : 'border',
					items : [sbBox, this.tbPanel]
				});
		return this;
	},
	addTaskButton : function(win) {
		return this.tbPanel.addButton(win, 'ux-taskbuttons-panel');
	},
	removeTaskButton : function(btn) {
		this.tbPanel.removeButton(btn);
	},
	setActiveButton : function(btn) {
		this.tbPanel.setActiveButton(btn);
	}
});
Ext.ux.TaskBarContainer = Ext.extend(Ext.Container, {
			initComponent : function() {
				Ext.ux.TaskBarContainer.superclass.initComponent.call(this);
				this.el = Ext.get(this.el) || Ext.getBody();
				this.el.setHeight = Ext.emptyFn;
				this.el.setWidth = Ext.emptyFn;
				this.el.setSize = Ext.emptyFn;
				this.el.setStyle({
							overflow : 'hidden',
							margin : '0',
							border : '0 none'
						});
				this.el.dom.scroll = 'no';
				this.allowDomMove = false;
				this.autoWidth = true;
				this.autoHeight = true;
				Ext.EventManager.onWindowResize(this.fireResize, this);
				this.renderTo = this.el;
			},
			fireResize : function(w, h) {
				this.fireEvent('resize', this, w, h, w, h);
			}
		});
Ext.ux.TaskButtonsPanel = Ext.extend(Ext.BoxComponent, {
	activeButton : null,
	enableScroll : true,
	scrollIncrement : 0,
	scrollRepeatInterval : 400,
	scrollDuration : .35,
	animScroll : true,
	resizeButtons : true,
	buttonWidth : 168,
	minButtonWidth : 118,
	buttonMargin : 2,
	buttonWidthSet : false,
	initComponent : function() {
		Ext.ux.TaskButtonsPanel.superclass.initComponent.call(this);
		this.on('resize', this.delegateUpdates);
		this.items = [];
		this.stripWrap = Ext.get(this.el).createChild({
					cls : 'ux-taskbuttons-strip-wrap',
					cn : {
						tag : 'ul',
						cls : 'ux-taskbuttons-strip'
					}
				});
		this.stripSpacer = Ext.get(this.el).createChild({
					cls : 'ux-taskbuttons-strip-spacer'
				});
		this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
		this.edge = this.strip.createChild({
					tag : 'li',
					cls : 'ux-taskbuttons-edge'
				});
		this.strip.createChild({
					cls : 'x-clear'
				});
	},
	addButton : function(win) {
		var li = this.strip.createChild({
					tag : 'li'
				}, this.edge);
		var btn = new Ext.ux.TaskBar.TaskButton(win, li);
		this.items.push(btn);
		if (!this.buttonWidthSet) {
			this.lastButtonWidth = btn.container.getWidth();
		}
		this.setActiveButton(btn);
		return btn;
	},
	removeButton : function(btn) {
		var li = document.getElementById(btn.container.id);
		btn.destroy();
		li.parentNode.removeChild(li);
		var s = [];
		for (var i = 0, len = this.items.length; i < len; i++) {
			if (this.items[i] != btn) {
				s.push(this.items[i]);
			}
		}
		this.items = s;
		this.delegateUpdates();
	},
	setActiveButton : function(btn) {
		this.activeButton = btn;
		this.delegateUpdates();
	},
	delegateUpdates : function() {
		if (this.resizeButtons && this.rendered) {
			this.autoSize();
		}
		if (this.enableScroll && this.rendered) {
			this.autoScroll();
		}
	},
	autoSize : function() {
		var count = this.items.length;
		var ow = this.el.dom.offsetWidth;
		var aw = this.el.dom.clientWidth;
		if (!this.resizeButtons || count < 1 || !aw) {
			return;
		}
		var each = Math.max(Math.min(Math.floor((aw - 4) / count)
								- this.buttonMargin, this.buttonWidth),
				this.minButtonWidth);
		var btns = this.stripWrap.dom.getElementsByTagName('button');
		this.lastButtonWidth = Ext.get(btns[0].id).findParent('li').offsetWidth;
		for (var i = 0, len = btns.length; i < len; i++) {
			var btn = btns[i];
			var tw = Ext.get(btns[i].id).findParent('li').offsetWidth;
			var iw = btn.offsetWidth;
			btn.style.width = (each - (tw - iw)) + 'px';
		}
	},
	autoScroll : function() {
		var count = this.items.length;
		var ow = this.el.dom.offsetWidth;
		var tw = this.el.dom.clientWidth;
		var wrap = this.stripWrap;
		var cw = wrap.dom.offsetWidth;
		var pos = this.getScrollPos();
		var l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
		if (!this.enableScroll || count < 1 || cw < 20) {
			return;
		}
		wrap.setWidth(tw);
		if (l <= tw) {
			wrap.dom.scrollLeft = 0;
			if (this.scrolling) {
				this.scrolling = false;
				this.el.removeClass('x-taskbuttons-scrolling');
				this.scrollLeft.hide();
				this.scrollRight.hide();
			}
		} else {
			if (!this.scrolling) {
				this.el.addClass('x-taskbuttons-scrolling');
			}
			tw -= wrap.getMargins('lr');
			wrap.setWidth(tw > 20 ? tw : 20);
			if (!this.scrolling) {
				if (!this.scrollLeft) {
					this.createScrollers();
				} else {
					this.scrollLeft.show();
					this.scrollRight.show();
				}
			}
			this.scrolling = true;
			if (pos > (l - tw)) {
				wrap.dom.scrollLeft = l - tw;
			} else {
				this.scrollToButton(this.activeButton, true);
			}
			this.updateScrollButtons();
		}
	},
	createScrollers : function() {
		var h = this.el.dom.offsetHeight;
		var sl = this.el.insertFirst({
					cls : 'ux-taskbuttons-scroller-left'
				});
		sl.setHeight(h);
		sl.addClassOnOver('ux-taskbuttons-scroller-left-over');
		this.leftRepeater = new Ext.util.ClickRepeater(sl, {
					interval : this.scrollRepeatInterval,
					handler : this.onScrollLeft,
					scope : this
				});
		this.scrollLeft = sl;
		var sr = this.el.insertFirst({
					cls : 'ux-taskbuttons-scroller-right'
				});
		sr.setHeight(h);
		sr.addClassOnOver('ux-taskbuttons-scroller-right-over');
		this.rightRepeater = new Ext.util.ClickRepeater(sr, {
					interval : this.scrollRepeatInterval,
					handler : this.onScrollRight,
					scope : this
				});
		this.scrollRight = sr;
	},
	getScrollWidth : function() {
		return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
	},
	getScrollPos : function() {
		return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
	},
	getScrollArea : function() {
		return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
	},
	getScrollAnim : function() {
		return {
			duration : this.scrollDuration,
			callback : this.updateScrollButtons,
			scope : this
		};
	},
	getScrollIncrement : function() {
		return (this.scrollIncrement || this.lastButtonWidth + 2);
	},
	scrollToButton : function(item, animate) {
		item = item.el.dom.parentNode;
		if (!item) {
			return;
		}
		var el = item;
		var pos = this.getScrollPos(), area = this.getScrollArea();
		var left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos;
		var right = left + el.offsetWidth;
		if (left < pos) {
			this.scrollTo(left, animate);
		} else if (right > (pos + area)) {
			this.scrollTo(right - area, animate);
		}
	},
	scrollTo : function(pos, animate) {
		this.stripWrap.scrollTo('left', pos, animate
						? this.getScrollAnim()
						: false);
		if (!animate) {
			this.updateScrollButtons();
		}
	},
	onScrollRight : function() {
		var sw = this.getScrollWidth() - this.getScrollArea();
		var pos = this.getScrollPos();
		var s = Math.min(sw, pos + this.getScrollIncrement());
		if (s != pos) {
			this.scrollTo(s, this.animScroll);
		}
	},
	onScrollLeft : function() {
		var pos = this.getScrollPos();
		var s = Math.max(0, pos - this.getScrollIncrement());
		if (s != pos) {
			this.scrollTo(s, this.animScroll);
		}
	},
	updateScrollButtons : function() {
		var pos = this.getScrollPos();
		this.scrollLeft[pos == 0 ? 'addClass' : 'removeClass']('ux-taskbuttons-scroller-left-disabled');
		this.scrollRight[pos >= (this.getScrollWidth() - this.getScrollArea())
				? 'addClass'
				: 'removeClass']('ux-taskbuttons-scroller-right-disabled');
	}
});
Ext.ux.TaskBar.TaskButton = function(win, el) {
	this.win = win;
	Ext.ux.TaskBar.TaskButton.superclass.constructor.call(this, {
		iconCls : win.iconCls,
		text : Ext.util.Format.ellipsis(win.title, 12),
		renderTo : el,
		handler : function() {
			if (win.minimized || win.hidden) {
				win.show();
			} else if (win == win.manager.getActive()) {
				win.minimize();
			} else {
				win.toFront();
			}
		},
		clickEvent : 'mousedown',
		template : new Ext.Template(
				'<table border="0" cellpadding="0" cellspacing="0" class="x-btn-wrap"><tbody><tr>',
				'<td class="ux-taskbutton-left"><i>&#160;</i></td><td class="ux-taskbutton-center"><em unselectable="on"><button class="x-btn-text" type="{1}" style="height:28px;">{0}</button></em></td><td class="ux-taskbutton-right"><i>&#160;</i></td>',
				"</tr></tbody></table>")
	});
};
Ext.extend(Ext.ux.TaskBar.TaskButton, Ext.Button, {
			onRender : function() {
				Ext.ux.TaskBar.TaskButton.superclass.onRender.apply(this,
						arguments);
				this.cmenu = new Ext.menu.Menu({
							items : [{
										text : '恢复窗口',
										icon : 'static/images/app/list-items.gif',
										handler : function() {
											if (!this.win.isVisible()) {
												this.win.show();
											} else {
												this.win.restore();
											}
										},
										scope : this
									}, {
										text : '最小化',
										icon : 'static/images/app/list-items.gif',
										handler : this.win.minimize,
										scope : this.win
									}, {
										text : '最大化',
										icon : 'static/images/app/list-items.gif',
										handler : this.win.maximize,
										scope : this.win
									}, '-', {
										text : '关闭窗口',
										icon : 'static/images/app/list-items.gif',
										handler : this.closeWin.createDelegate(
												this, this.win, true),
										scope : this.win
									}]
						});
				this.cmenu.on('beforeshow', function() {
							var items = this.cmenu.items.items;
							var w = this.win;
							items[0].setDisabled(w.maximized !== true
									&& w.hidden !== true);
							items[1].setDisabled(w.minimized === true);
							items[2].setDisabled(w.maximized === true
									|| w.hidden === true);
						}, this);
				this.el.on('contextmenu', function(e) {
							e.stopEvent();
							if (!this.cmenu.el) {
								this.cmenu.render();
							}
							var xy = e.getXY();
							xy[1] -= this.cmenu.el.getHeight();
							this.cmenu.showAt(xy);
						}, this);
			},
			closeWin : function(cMenu, e, win) {
				if (!win.isVisible()) {
					win.show();
				} else {
					win.restore();
				}
				win.close();
			}
		});